#!/bin/sh

if test $# -ne 0; then
    case $1 in
        develop)
	    echo Preparing to build developmental version of MudOS driver ...
	    OPTIMIZE="-Wall -Wundef -DPEDANTIC -pedantic -Wmissing-declarations"
	    DEBUG="-g -DDEBUG -DDEBUG_MACRO"
            ;;
        debug)
	    echo Preparing to build debugging version of MudOS driver ...
	    OPTIMIZE=
	    DEBUG="-g -DDEBUG"
            ;;
        *)
	    echo Unknown build type
	    exit 1
            ;;
    esac
else
    echo Preparing to build standard MudOS driver ...
fi

# If this is uncommented, the specified 'make' is used instead of looking for
# one 
#MAKE=make

# define this to be where you want the temporary compiled files to go
# (only used with GNU make)
OBJDIR=obj

# change this if you wish the driver binary to be named something else
DRIVER_BIN=driver

# uncomment PROOF if using CenterLine's TestCenter to debug the driver.
#PROOF=proof

# Set INSTALL_DIR to the directory where you want to install the executables.
INSTALL_DIR="../bin"

#Enable warnings from the compiler (gcc), if wanted.
#WARN=-Wall
 
#Use this with gcc if you have lots of RAM, speeds up compile
#PIPE=-pipe

# define profiling if you want it
# note: the gmon.out file will likely be written in the mudlib dir.
# PROFILE_ON controls whether or not monitoring is active at driver
# startup.  Comment PROFILE_ON to make profiling not active at startup.
# Use moncontrol(1) efun to enable profiling and moncontrol(0) to turn
# it off.
#PROFILE_ON="-DPROFILE_ON"
# Uncomment this if you want to enable profiling of the driver (gcc)
#PROFIL="-pg -DPROFILING $(PROFILE_ON)"
 
# Enable run time debugging
#DEBUG="-g"
# With extra driver debug code
#DEBUG="-g -DDEBUG" 
# For DEC Alpha: to have optimization and debugging
#DEBUG="-g3 -DDEBUG"
# Prevent -DDEBUG from aborting the driver (when in -DDEBUG mode)
#DEBUG_NON_FATAL="-DDEBUG_NON_FATAL"
# Compile in debug() macro code
#DEBUG_MACRO="-DDEBUG_MACRO"
 
# define this if you want to specify (compiler) optimization.
# 
# if nothing is defined here, and DEBUG is not defined, something appropriate
# to the compiler in question is used.
#
# *WARNING* using high levels of optimization (e.g. -O3) can cause some
# compilers to produce incorrect code.  If the driver is behaving
# inexplicably, try using a lower level of optimization (or none).
#
# Uncomment one or none of the following optimization lines.
#
# -O is usually a safe level of optimization for most compilers
#OPTIMIZE="-O"
# high optimization for gcc:
#OPTIMIZE="-O2 -fstrength-reduce"
# uncomment below for RS/6000(AIX) xlc compiler only.
# remove the -Q if xlc complains.
#OPTIMIZE="-O -Q"
# might need this one with newer versions of AIX (ie 3.2.4)
#OPTIMIZE="-O -Q -qMAXMEM=16000"
# high optimization for HP-UX 7.x/8.x's cc (don't use with 9.x)
#OPTIMIZE="+O3 +Obb3000"
# MIPS R3000 running EP/IX Version 1.4.3. Compiler is RISCompiler C 2.11 (cc).
#OPTIMIZE="-Olimit 1802"
# DEC Alpha's cc's highest optimization: -O5
#OPTIMIZE="-O -Olimit 2000"
# DEC Ultrix's cc's highest optimization:
#OPTIMIZE="-O2 -Olimit 5000"
# high optimization for cc on SGI
#OPTIMIZE="-O2 -Olimit 2500"
 
# System V Release 4 (386/486 or if using Sun's cc under Solaris 2.x)
# ARCH: need a way to detect this
#OSFLAGS=-DSVR4

# MIPS R3000 running EP/IX Version 1.4.3. Compiler is RISCompiler C 2.11 (cc).
# ARCH: this one too
#OSFLAGS=-I/usr/include/bsd

# Solaris (SunOS 5): for BSD compatible ioctl()
# If using CC=cc, you can also add:
#      -w     to turn off warnings, in order to get a cleaner compile
# For 5.4, also add the following:
#      -I/usr/bsdinclude
# ARCH: anyone figured a good hack to detect this one yet?
#OSFLAGS="-DBSD_COMP -DSunOS_5"

# SCO 3.2v4.2
# ARCH: *sigh* and this one ...
#OSFLAGS=-DSCO

# try uncommenting this if you are using gcc and at runtime you see socket
# errors saying that the "set socket nonblocking" operation is not supported.
# That error is caused by old-style macros (that gcc doesn't normally grok)
# used by ioctl on some systems.
#NEED_OLD_CPP=-traditional-cpp

# Location of libmsgql.a, if you are using PACKAGE_DB
#EXTRALIBS=-L/usr/local/lib -lmsql

####### END OF USER CONFIGURABLE OPTIONS

echo "Trying out some stuff to see what works; ignore errors ..."

# Mac OS X needs this in order to build properly with gcc < 3
if test "`uname`" = "Darwin"; then
    GCC_MAJOR="`gcc -v 2>&1 | grep "gcc version" | cut -d ' ' -f 3 | cut -d '.' -f 1`"
    GCC_MINOR="`gcc -v 2>&1 | grep "gcc version" | cut -d ' ' -f 3 | cut -d '.' -f 2`"
    if test "$GCC_MAJOR" -eq "2"; then
        NEED_OLD_CPP=-traditional-cpp
    fi
fi

# 
# Figure out what make is, and how to invoke it
# 
if test "${MAKE-x}" = "x"; then
    gmake nothing
    if test $? -eq 0; then
        MAKE=gmake
        MAKEFILE=GNUmakefile
    else
        make nothing
        if test $? -eq 0; then
            MAKE=make
            tmp=`make which_makefile 2>/dev/null | grep -v echo`
            if test "x$tmp" = "xMakeIsGNU"; then
                MAKEFILE=GNUmakefile
            else
                MAKEFILE=Makefile
		OBJDIR=
            fi
        else
            echo 'FATAL ERROR: Cannot find make or gmake'
            exit
        fi
    fi
else
    tmp=`make which_makefile 2>/dev/null | grep -v echo`
    if test "x$tmp" = "xMakeIsGNU"; then
        MAKEFILE=GNUmakefile
    else
        MAKEFILE=Makefile
	OBJDIR=
    fi
fi

echo MAKE=$MAKE >Makefile.tmp

#
# Figure out what to use for CC
#
cat >comptest.c <<END
int main() {
}
END
xlc comptest.c
if test $? -eq 0; then
    CC=xlc
    if test "${DEBUG-x}" = "x"; then
        OPTIMIZE=${OPTIMIZE-"-O3 -Q -qMAXMEM=16000"}
    fi
else
    gcc comptest.c
    if test $? -eq 0; then
        CC=gcc
        if test "${DEBUG-x}" = "x"; then
            OPTIMIZE=${OPTIMIZE-"-O2 -fstrength-reduce"}
        fi
	GNUC=1
	CCFLAGS=-D__USE_FIXED_PROTOTYPES__
    else
        clcc comptest.c
        if test $? -eq 0; then
            CC=clcc
            if test "${DEBUG-x}" = "x"; then
                OPTIMIZE=${OPTIMIZE-"-O"}
            fi
        else
            cc comptest.c
            if test $? -eq 0; then
                CC=cc
                if test "${DEBUG-x}" = "x"; then
                    OPTIMIZE=${OPTIMIZE-"-O"}
		    cat >comptest.c <<END
#ifndef __GNUC__
Oh darn it's not gcc
#endif
END
		    cc comptest.c
		    if test $? -eq 0; then
			OPTIMIZE=${OPTIMIZE-"-O2 -fstrength-reduce"}
			GNUC=1
		    fi
                fi
            else
                echo "FATAL ERROR: Cannot find a C compiler"
                exit
            fi
        fi
    fi
fi

#
# are we using gcc on a 486?
#
if test $GNUC; then
    tmp=`uname -m`
    if test "x$tmp" = "xi486" -o "x$tmp" = "xi586"; then
        OPTIMIZE="$OPTIMIZE -m486"
    fi
fi

#
# Figure out how to run CPP
#

cat >comptest.c <<END
#define foo
Make this fail if we actually get compiled
END
$CC -E comptest.c >/dev/null
if test $? -eq 0; then
    CPP="$CC -E $NEED_OLD_CPP"
else
    cpp comptest.c >/dev/null
    if test $? -eq 0; then
        CPP="cpp"
    else
        $CC -E -traditional-cpp comptest.c >/dev/null
	if test $? -eq 0; then
	    CPP="$CC -E -traditional-cpp"
	else
	    echo "FATAL ERROR: Can't figure out how to run the C preprocessor"
            exit
	fi
    fi
fi

#
# Figure out what to use for install
#
mkdir tmp
cat >insttest <<END
whatever
END
rm tmp/insttest
install -f insttest tmp
if test $? -eq 0 && test -f tmp/insttest; then
    INSTALL="install -f"
else
    rm tmp/insttest
    install -c insttest tmp
    if test $? -eq 0 && test -f tmp/insttest; then
       INSTALL="install -c"
    else
       INSTALL="cp"
    fi
fi

cat >comptest.c <<END
void foo() { }
END
$CC -c comptest.c -o comptest.o

#
# Check if ranlib exists/is needed.  Also check ar.
#
cat >comptest.c <<END
int if_you_are_reading_this_you_must_be_bored() { return 1; }
END
$CC -c comptest.c

ar rcu comptest.a comptest.o
if test $? -ne 0; then
    echo "FATAL ERROR: Could not find ar."
    exit
fi
ranlib comptest.a
if test $? -eq 0; then
    RANLIB=ranlib    
else
    RANLIB=/bin/true
fi

#
# Find yacc/bison/byacc
#
cat >comptest.y <<END
%token FOO
%%
all: FOO
END
bison comptest.y
if test $? -eq 0 && test $CC != "xlc"; then
    YACC="bison -d -y"
else
    byacc comptest.y
    if test $? -eq 0; then
        YACC="byacc -d"
    else
        yacc comptest.y
        if test $? -eq 0; then
            YACC="yacc -d"
        else
            echo "FATAL ERROR: Could not find bison or yacc."
            exit
        fi
    fi
fi

# Some of these are probably unnecessary
CFLAGS="$CCFLAGS $OSFLAGS $WARN $PROFIL $DEBUG $DEBUG_MACRO $DEBUG_NON_FATAL $STR $PIPE $NEED_OLD_CPP $EXPORT_DYNAMIC"

#
# Determine system type
#
cat >comptest.c <<END
#include <stdio.h>
#include "arch.h"
int main() {
    printf("%s\n", ARCH);
}
END
$CC $CFLAGS comptest.c
ARCH=`./a.out`

cat >comptest.c <<END
int main(int argc, char **argv) { return 0; }
END

case $ARCH in
    AIX)
        OSFLAGS="$OSFLAGS -D_BSD -D_ALL_SOURCE"
	CFLAGS="$CFLAGS -D_BSD -D_ALL_SOURCE"
        ;;    
    Solaris)
	OSFLAGS="$OSFLAGS -DSunOS_5"
	CFLAGS="$CFLAGS -DSunOS_5"
	;;
    Linux*)
        EXPORT_DYNAMIC=-rdynamic
	;;
    FreeBSD)
	cc -export-dynamic comptest.c
	if test $? -eq 0; then
	    EXPORT_DYNAMIC=-export-dynamic
	else
	    cc -rdynamic comptest.c
	    if test $? -eq 0; then
		EXPORT_DYNAMIC=-rdynamic
	    fi
	fi
	;;
esac

#
# check for some missing functions
#
rm a.out
cat >comptest.c <<END
int main() {
strchr(0,0); strrchr(0,0);
}
END
$CC $CFLAGS comptest.c
if test ! -f a.out; then
    STR="-Dstrchr=index -Dstrrchr=rindex"
fi

rm a.out
cat >comptest.c <<END
int main() {
memcpy(0,0,0);memset(0,0,0);strtol(0,0,0);strcspn(0,0);
}
END
$CC $CFLAGS comptest.c
if test ! -f a.out; then
    STRFUNCS=strfuncs.o
fi

CFLAGS="$CCFLAGS $OSFLAGS $WARN $PROFIL $DEBUG $DEBUG_MACRO $DEBUG_NON_FATAL $STR $PIPE $NEED_OLD_CPP $INCLUDE $EXPORT_DYNAMIC"
if test ! "$OBJDIR" = ""; then
    mkdir $OBJDIR
fi

echo SHELL=/bin/sh >>Makefile.tmp
echo OBJDIR=$OBJDIR >>Makefile.tmp
echo DRIVER_BIN=$DRIVER_BIN >>Makefile.tmp
echo PROOF=$PROOF >>Makefile.tmp
echo STRFUNCS=$STRFUNCS >>Makefile.tmp
echo INSTALL=$INSTALL >>Makefile.tmp
echo INSTALL_DIR=$INSTALL_DIR >>Makefile.tmp
echo OPTIMIZE=$OPTIMIZE >>Makefile.tmp
echo CPP=$CPP >>Makefile.tmp
echo CFLAGS=$CFLAGS >>Makefile.tmp
echo CC=$CC >>Makefile.tmp
echo YACC=$YACC >>Makefile.tmp
echo RANLIB=$RANLIB >>Makefile.tmp
echo A=a >>Makefile.tmp
echo O=o >>Makefile.tmp

echo "***************** Configuration completed **************"
echo "Installing MudOS on $ARCH"
echo
echo "Using $INSTALL to install binaries in $INSTALL_DIR."
echo "Using $CPP for preprocessing."
echo "Using $CC $CFLAGS $OPTIMIZE to compile."
echo "Using $YACC $YFLAGS to make the compiler."
echo "Edit $MAKEFILE if this is not what you want"
echo
echo "Otherwise, type '$MAKE' to build MudOS, then '$MAKE install'."

cat Makefile.tmp ${MAKEFILE}.in >$MAKEFILE
rm Makefile.tmp

if test $MAKEFILE = Makefile; then
cat >GNUmakefile <<END
all:
	@echo MudOS is currently configured to use 'Makefile'.  Edit 'build.MudOS'
	@echo if this is not what you want.

.DEFAULT:
	@echo MudOS is currently configured to use 'Makefile'.  Edit 'build.MudOS'
	@echo if this is not what you want.

nothing:

which_makefile:
	echo MakeIsGNU
END
else
cat >Makefile <<END
all:
	@echo MudOS is currently configured to use 'GNUmakefile'.  Edit 'build.MudOS'
	@echo if this is not what you want.

.DEFAULT:
	@echo MudOS is currently configured to use 'GNUmakefile'.  Edit 'build.MudOS'
	@echo if this is not what you want.

nothing:

which_makefile:
	echo MakeIsMake
END
fi
